#!/bin/bash
# usage: 
# ========================  <配置在jenkins脚本里面的形式>  =========================
# # 变量定义
# # 前置条件，项目需要被设置成公开项目（这个又需要其最近的父群组被设置成公开项目）
# # 查看和编辑本项目的文件 这个也需要设置为公开
# url_jenkins_scripts="http://gitlab.lovego2016.com/t-ops/g-ops/ops-scripts/public/jenkins/raw/master"
# file_build="build_t.sh"
# # 下载脚本
# cd $WORKSPACE
# curl -s -o ./$file_build $url_jenkins_scripts/devb/java/$file_build
# # 下面的 $WORKSPACE 是jenkins的内置变量
# sed -i "/^WORKSPACE=/ c\WORKSPACE=$WORKSPACE" $file_build
# # 执行脚本
# bash $file_build

# ==========================  <引入jenkins变量>  =================================
WORKSPACE=


# ==========================  <下载文件>  =================================
# 进入工作目录
cd $WORKSPACE
[ ! -d "./jenkins_build" ]               && mkdir -p "./jenkins_build"
[ ! -d "./jenkins_build/docker" ]        && mkdir -p "./jenkins_build/docker"
[ ! -d "./jenkins_build/kubernetes" ]    && mkdir -p "./jenkins_build/kubernetes"
# 在脚本里重新定义一次gitlab的下载路径
url_jenkins_scripts="http://gitlab.lovego2016.com/t-ops/g-ops/ops-scripts/public/jenkins/raw/master"
# 下载构建需要的配置文件,其中有两个空文件
# docker
# curl -s -o ./jenkins_build/docker/Dockerfile       $url_jenkins_scripts/devb/docker/Dockerfile_java
curl -s -o ./jenkins_build/docker/Dockerfile_java  $url_jenkins_scripts/devb/docker/Dockerfile_java
curl -s -o ./jenkins_build/docker/Dockerfile_nginx $url_jenkins_scripts/devb/docker/Dockerfile_nginx
# kubernetes
# curl -s -o ./jenkins_build/kubernetes/deployment.yml                        $url_jenkins_scripts/devb/kubernetes/deployment.yml
curl -s -o ./jenkins_build/kubernetes/deployment_1.yml                      $url_jenkins_scripts/devb/kubernetes/deployment_1.yml
curl -s -o ./jenkins_build/kubernetes/deployment_2_java_configuration.yml   $url_jenkins_scripts/devb/kubernetes/deployment_2_java_configuration.yml
curl -s -o ./jenkins_build/kubernetes/deployment_2_java_eureka.yml          $url_jenkins_scripts/devb/kubernetes/deployment_2_java_eureka.yml
curl -s -o ./jenkins_build/kubernetes/deployment_2_java_other.yml           $url_jenkins_scripts/devb/kubernetes/deployment_2_java_other.yml
curl -s -o ./jenkins_build/kubernetes/deployment_2_nginx_erp.yml            $url_jenkins_scripts/devb/kubernetes/deployment_2_nginx_erp.yml
curl -s -o ./jenkins_build/kubernetes/service.yml                           $url_jenkins_scripts/devb/kubernetes/service.yml
# 命名构建三剑客文件
path_dockerfile="$WORKSPACE/jenkins_build/docker/Dockerfile"
path_k8s_deployment="$WORKSPACE/jenkins_build/kubernetes/deployment.yml"
path_k8s_service="$WORKSPACE/jenkins_build/kubernetes/service.yml"



# =============================== <打包成docker镜像并推送到harbor仓库> ===========================
# ------------------------------------变量定义---------------------------------------

# iamge_env: 镜像环境，在harbor里作为表示为项目
# k8s_env: 发布环境，微服务启动时的参数中的变量
if [ "$IP_LAN1" = "192.168.101.22" ];
then
	iamge_env="dev-env"
    registry_url="harbor.lovego.xin"
    k8s_env="dev"
elif [ "$IP_LAN1" = "192.168.101.29" ];
then
	iamge_env="dev-env"
    registry_url="harbor.lovego2016.com"
    k8s_env="dev"
elif [ "$IP_LAN1" = "192.168.101.58" ];
then
	iamge_env="tesb-env"
    registry_url="harbor.lovego2016.com"
	k8s_env="tesb"    
elif [ "$IP_LAN1" = "192.168.101.59" ];
then
	iamge_env="tesm-env"
    registry_url="harbor.lovego2016.com"
	k8s_env="tesm"
elif [ "$IP_LAN1" = "192.168.101.89" ];
then
	iamge_env="prep-env"
    registry_url="harbor.lovego2016.com"
	k8s_env="prep"        
fi

# echo $iamge_env
# 镜像名定义
find_jar=$(find $WORKSPACE -name "target" -type d)
if [ ! -z "$find_jar" ]
then
    # echo "java"
    # 服务类型为java应用
    image_name="$(ls $WORKSPACE/target | egrep *.jar$ | awk -F'.' '{print $1}')"
else
    # echo "html"
    # 服务类型为其他，例如html应用
    source $WORKSPACE/src/main/image_info.sh
fi
# 端口名定义，按照应该部署的顺序排序
if [ "$image_name" == "eureka-service" ]
then
    container_port1="8761"; svc_node_port1="30000"

elif [ "$image_name" == "configuration-service" ]
then
    container_port1="8888"; svc_node_port1="30002"

elif [ "$image_name" == "zipkin-service" ]
then
    container_port1="9888"; svc_node_port1="30005"

elif [ "$image_name" == "redis-service" ]
then
    container_port1="9018"; svc_node_port1="30004"

elif [ "$image_name" == "common-service" ]
then
    container_port1="9008"; svc_node_port1="30006"

elif [ "$image_name" == "user-service" ]
then
    container_port1="9012"; svc_node_port1="30007"

elif [ "$image_name" == "erp" ]
then
    container_port1="9033"; svc_node_port1="30010"

elif [ "$image_name" == "front" ]
then
    container_port1="9022"; svc_node_port1="30008"

elif [ "$image_name" == "gateway-back-end" ]
then
    container_port1="9090"; svc_node_port1="30009"

elif [ "$image_name" == "product-service" ]
then
    container_port1="9017"; svc_node_port1="30011"

elif [ "$image_name" == "stock-service" ]
then
    container_port1="9013"; svc_node_port1="30012"

elif [ "$image_name" == "supplier-service" ]
then
    container_port1="9025"; svc_node_port1="30013"        

elif [ "$image_name" == "lovego-erp-admin" ]
then
    container_port1="80";   svc_node_port1="30101"
fi
# k8s 的 service的cluster ip的 port一般和 容器端口一致
svc_cluster_port1="$container_port1"
# image_name="common-service"
# echo $container_port1


# git版本号，和下面一起用作镜像的tag名
git_revision=$(git show --oneline | head -n 1 | awk '{print $1}')
image_version_1="v$(date +%Y%m%d_%H%M%S)_${git_revision}"
image_version_2="latest"
# 镜像完整名（加上仓库和在仓库的项目）
image_url="$registry_url/$iamge_env/$image_name"
image_url_v1="$image_url:$image_version_1"
image_url_v2="$image_url:$image_version_2"



# ----------------------------------构建docker镜像-------------------------------------
# 进入工作目录
cd $WORKSPACE

# 合并文件: 先合并,再替换变量
# 第一个文件是直接覆盖到 deployment.yml
if [ "$image_name" == "lovego-erp-admin" ]
then
    cat ./jenkins_build/docker/Dockerfile_nginx >> ./jenkins_build/docker/Dockerfile

else
    cat ./jenkins_build/docker/Dockerfile_java >> ./jenkins_build/docker/Dockerfile
fi
# 替换文件内的变量
sed -i "s/VAR_IMAGE_NAME/$image_name/g" $path_dockerfile
sed -i "s/VAR_CONTAINER_PORT1/$container_port1/g" $path_dockerfile
# 更新 FROM 字段后面的镜像，如果不更新的话，由于tag一样，会取本地缓存
from_image_url=$(cat $path_dockerfile | egrep -v ^# | grep 'FROM' | awk '{print $2}')
docker pull $from_image_url
# docker pull harbor.lovego2016.com/base/centos7-nginx1-12:latest
# docker pull harbor.lovego2016.com/base/centos7-jdk8:latest
# 构建镜像并打tag
docker build -t $image_url_v1 -f $path_dockerfile .
# 打最新的tag
docker tag $image_url_v1 $image_url_v2
# 推送镜像到仓库
docker push $image_url_v1
docker push $image_url_v2


# 如果出现登陆异常,请手动执行登陆
# docker login -u admin -p Harbor12345 harbor.test.com


# --------------------------------清理本地jenkins历史tag----------------------------------
# 只保留latest及v开头最新的5个，一共6个
# 如果不足6个的话，会失败，所以仅在大于6个的时候才删除
image_tag_num=$(docker images | grep $image_url | wc -l)
if [ $image_tag_num -gt 6 ];
then
	docker rmi $(docker images | grep $image_url | grep -v latest | sort -k2 -rn | sed '1,5 d' | awk '{print $3}') --force
fi
# 注：对于一个服务，即使一模一样的git版本，所生成的镜像的id也不一样






# ======================== <发布到Kubernetes集群内部，若已发布，则更新版本> =========================
# --------------------------------发布到Kubernetes----------------------------------
# 前置条件1
# 需要自动为jenkins配置Kubernetes的kubectl管理
# kubectl config view
# kubectl get nodes
# 前置条件2
# 需要在rancher上面，保存一个具有harbor管理员权限的账户，不然kubernetes在创建deployment拉取不下来镜像
# 

# 镜像名
# image_name="$(ls $WORKSPACE/target | egrep *.jar$ | awk -F'.' '{print $1}')"
deployment_name="deploy-$image_name"
service_name="svc-$image_name"
#container_name="container-$image_name"

# 合并文件: 先合并,再替换变量
# 第一个文件是直接覆盖到 deployment.yml
cat ./jenkins_build/kubernetes/deployment_1.yml > ./jenkins_build/kubernetes/deployment.yml
# 第二个文件时向 deployment.yml 进行追加
if [ "$image_name" == "lovego-erp-admin" ]
then
    cat ./jenkins_build/kubernetes/deployment_2_nginx_erp.yml >> ./jenkins_build/kubernetes/deployment.yml

elif [ "$image_name" == "eureka-service" ]
then
    cat ./jenkins_build/kubernetes/deployment_2_java_eureka.yml >> ./jenkins_build/kubernetes/deployment.yml

elif [ "$image_name" == "configuration-service" ]
then
    cat ./jenkins_build/kubernetes/deployment_2_java_configuration.yml >> ./jenkins_build/kubernetes/deployment.yml

else
    cat ./jenkins_build/kubernetes/deployment_2_java_other.yml >> ./jenkins_build/kubernetes/deployment.yml
fi

# 替换文件内的变量
# 变量image_url_v1的值有 / ，需要把sed s的符合改成 #
# deployment.yml
sed -i "s#VAR_IMAGE_URL#$image_url_v1#g"              $path_k8s_deployment
sed -i "s/VAR_IMAGE_NAME/$image_name/g"               $path_k8s_deployment
sed -i "s/VAR_CONTAINER_PORT1/$container_port1/g"     $path_k8s_deployment
sed -i "s/VAR_K8S_ENV/$k8s_env/g"                     $path_k8s_deployment
# service.yml
sed -i "s/VAR_IMAGE_NAME/$image_name/g"               $path_k8s_service
sed -i "s/VAR_CONTAINER_PORT1/$container_port1/g"     $path_k8s_service
sed -i "s/VAR_SVC_CLUSTER_PORT1/$svc_cluster_port1/g" $path_k8s_service
sed -i "s/VAR_SVC_NODE_PORT1/$svc_node_port1/g"       $path_k8s_service


if [ "$(kubectl get deployments $deployment_name)" ]
then
	deployment_exist=1
	# 如果Deployment已存在，则自动从部署文件更新配置（含版本）
    # kubectl set image deployment/$deployment_name $container_name=$image_url_v1
    # apply更新的方式更为完善
    kubectl apply -f $path_k8s_deployment --record
else
	deployment_exist=0
    # 如果Deployment不存在，则创建deployment
	kubectl create -f $path_k8s_deployment --record
fi
# echo $deployment_exist

if [ "$(kubectl get services $service_name)" ]
then
	service_exist=1
    # 如果sercice已存在，则自动从部署文件更新配置
    kubectl apply -f $path_k8s_service --record
else
	service_exist=0
    # 如果sercice不存在，则创建
    kubectl create -f $path_k8s_service --record
fi
# echo $service_exist











